package com.sky.service.impl;

import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkSpaceService workspaceService;

    /**
     * 营业额统计
     */
    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = makeDateList(begin, end);
        List<Double> turnoverList = reportMapper.getTurnoverStatistics(dateList);
        return new TurnoverReportVO(
                StringUtils.join(dateList, ","),
                StringUtils.join(turnoverList, ","));
    }

    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = makeDateList(begin, end);
        List<Integer> totalUserList = reportMapper.getUserStatistics(dateList);
        List<Integer> newUserList = reportMapper.getNewUserStatistics(dateList);
        return new UserReportVO(
                StringUtils.join(dateList, ","),
                StringUtils.join(totalUserList, ","),
                StringUtils.join(newUserList, ",")
        );
    }

    @Override
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = makeDateList(begin, end);

        Integer totalOrderCount = reportMapper.getTotalOrderCount(dateList);
        List<Integer> validOrderCountList = reportMapper.getValidOrderCountList(dateList);
        Integer validOrderCount = 0;
        for (Integer i : validOrderCountList) {
            validOrderCount += i;
        }
        Double orderCompletionRate = (double) validOrderCount / (double) totalOrderCount;
        orderCompletionRate = new java.math.BigDecimal(orderCompletionRate)
                .setScale(2, java.math.RoundingMode.HALF_UP)
                .doubleValue();

        return new OrderReportVO(
                StringUtils.join(dateList, ","),
                StringUtils.join(reportMapper.getOrderCountList(dateList), ","),
                StringUtils.join(reportMapper.getValidOrderCountList(dateList), ","),
                totalOrderCount,
                validOrderCount,
                orderCompletionRate
        );
    }

    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        return new SalesTop10ReportVO(
                StringUtils.join(reportMapper.getTop10NameList(begin, end), ","),
                StringUtils.join(reportMapper.getTop10NumberList(begin, end), ",")
        );
    }

    /**
     * 导出Excel
     */
    @Override
    public void exportExcel(HttpServletResponse response) {
        //1．查询数据库，获取营业数据---查询最近30天的运营数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);
        LocalDate dateEnd = LocalDate.now().minusDays(1);
        List<LocalDate> dateList = makeDateList(dateBegin, dateEnd);
        //査询概览数据
        BusinessDataVO businessDataVO = workspaceService.getBusinessData(dateList);

        //2，通过PoI将数据写入到Excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            //基于模板文件创建一个新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(in);
            // 将数据写入到Excel文件中
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(1).getCell(1).setCellValue("时间: " + dateBegin + " ——— " + dateEnd);

            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());//营业额
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());//订单完成率
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());//新增用户数
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());//有效订单数
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());//平均客单价

            for (int i = 0; i < dateList.size(); i++) {
                LocalDate date = dateList.get(i);
                row = sheet.getRow(i + 7);
                // 检查行是否存在，不存在则创建
                if (row == null) {
                    row = sheet.createRow(i + 7);
                }

                // 确保所需的单元格都存在
                if (row.getCell(1) == null) row.createCell(1);
                if (row.getCell(2) == null) row.createCell(2);
                if (row.getCell(3) == null) row.createCell(3);
                if (row.getCell(4) == null) row.createCell(4);
                if (row.getCell(5) == null) row.createCell(5);
                if (row.getCell(6) == null) row.createCell(6);

                row.getCell(1).setCellValue(date.toString());
                List<LocalDate> tempDateList = new ArrayList<>();
                tempDateList.add(date);
                BusinessDataVO businessData = workspaceService.getBusinessData(tempDateList);
                row.getCell(2).setCellValue(businessData.getTurnover());//营业额
                row.getCell(3).setCellValue(businessData.getValidOrderCount());//有效订单数
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());//订单完成率
                row.getCell(5).setCellValue(businessData.getUnitPrice());//平均客单价
                row.getCell(6).setCellValue(businessData.getNewUsers());//新增用户数
            }

            //3，通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //4，关闭
            out.close();
            excel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List<LocalDate> makeDateList(LocalDate begin, LocalDate end) {
        List<LocalDate> dataList = new ArrayList<>();
        while (!begin.isAfter(end)) {
            dataList.add(begin);
            begin = begin.plusDays(1);
        }
        return dataList;
    }
}

